package secuDropper.core.security;

import java.security.SecureRandom;
import java.util.logging.Logger;

import org.bouncycastle.crypto.StreamCipher;
import org.bouncycastle.crypto.engines.Salsa20Engine;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;

import secuDropper.core.util.StringUtils;

/**
 * @author Matthias Hauser
 */
public class SecurityHandler {

	private Salsa20Engine encoder;
	private Salsa20Engine decoder;
	private boolean initialized = false;
	private final String password;

	private static final Logger LOGGER = Logger
			.getLogger("secuDropper.core.security");

	/**
	 * Constructs a new instance of {@link SecurityHandler}. Don't forget to
	 * call init() to initiate the {@link StreamCipher} encoder and decoder.
	 * 
	 * @param key
	 *            the password. must be 16 or 32 bytes, otherwise it will be
	 *            padded or truncated as appropriate
	 */
	public SecurityHandler(final String key) {
		if (key == null || key.equals(""))
			throw new IllegalArgumentException(
					"password may not be null or empty");

		final int keyLength = key.length();
		if (keyLength != 16 && keyLength != 32) {
			LOGGER.warning("key must be 16 or 32 bytes, so it will be padded or truncated as appropriate");
		}
		password = keyLength > 16 ? StringUtils.padnulls(key, 32) : StringUtils
				.padnulls(key, 16);
	}

	public boolean init() {
		byte[] keyBytes = password.getBytes();
		KeyParameter keyparam = new KeyParameter(keyBytes);

		SecureRandom random = new SecureRandom(keyBytes);
		byte nonce[] = new byte[8];
		random.nextBytes(nonce);

		ParametersWithIV params = new ParametersWithIV(keyparam, nonce);

		encoder = new Salsa20Engine();
		encoder.init(true, params);

		decoder = new Salsa20Engine();
		decoder.init(true, params);

		initialized = true;
		return true;
	}

	public StreamCipher getEncoder() {
		return encoder;
	}

	public StreamCipher getDecoder() {
		return decoder;
	}

	protected boolean isInitialized() {
		return initialized;
	}
}
